﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Frogism.Core;
using Frogism.Domain;

namespace Frogism.Web.Controllers {
    [Authorize]
    public class MoneyController : FrogControllerBase
    {
      protected bool IsTopher() {
        if((string)HttpContext.Session["UserName"] == "topher") {
          return true;
        } else {
          RedirectToAction("Login", "Home");
           // View("Login");
          return false;
        }
      }
   
        public ViewResult Index() {
            // Add action logic here
            MoneyManager mm = new MoneyManager();
            BudgetManager bm = new BudgetManager();
            IEnumerable<IAccount> accounts = mm.GetAll();
          
            DashboardViewData dashboardViewData = new DashboardViewData(
               accounts,bm.GetAll(accounts),mm.GetNetWorth(accounts));
           return View("Dashboard", dashboardViewData);
        }
      //  public ActionResult MarketAdjustUpdate(int Id, decimal newBalance) {
       
        public ActionResult MarketAdjustUpdate(int Id, FormCollection form)
        {
            int aId = Id;
          MoneyManager mm = new MoneyManager();
          IAccount account = mm.Get(aId);
          decimal newBalance;
          if (decimal.TryParse(form["newBalance"],out newBalance))
          {
              ITransaction trans = MarketAdjuster.Adjust(account, newBalance);
              TransactionManager tm = new TransactionManager();
              tm.Create(trans);
              return RedirectToAction("Index");
          }
          else
          {
              ViewData.ModelState.AddModelError("newBalance", "New balance was not a valid number.");

              return View("MarketAdjustModal", account);
          }
        }

        
        public ViewResult MarketAdjust(int Id)
        {
          MoneyManager mm = new MoneyManager();
          IAccount account = mm.Get(Id);
      //    ModelState.AddModelError("newBalance", "You must specified a valid number");
          return View("MarketAdjustModal",account);
        }
        
        public ViewResult All()
        {
                   TransactionManager tm = new TransactionManager();
          TransactionViewData transactionViewData = 
              new TransactionViewData(
                "All",null,                
                tm.GetAll().OrderByDescending(t=>t.TransactionDate).ToCollection<ITransaction>()
                );
          return View("TransactionList", transactionViewData);
        }

        public ViewResult UnConfirmed()
        {
          TransactionManager tm = new TransactionManager();
          TransactionViewData transactionViewData = 
            new TransactionViewData("UnConfirmed",null,tm.GetUnConfirmed());
          return View("TransactionList", transactionViewData);
        }

        public ViewResult ViewByAccount(int id)
        {
          MoneyManager am = new MoneyManager();
          Collection<ITransaction> ts = am.Get(id).Transactions.OrderByDescending(t => t.TransactionDate).ToCollection<ITransaction>();

          TransactionViewData transactionViewData = new TransactionViewData("ViewByAccount",id,ts);

          IAccount account = am.Get(id);
            if(account.AccountType == DBConst.AccountTypeMortgage){

                ViewData["MortgageGraph"] = ts;
            }
          return View("ViewByAccount", transactionViewData);
        }

        public ViewResult Categories()
        {
          CategoryManager mm = new CategoryManager();
          return View("CategorySummary", mm.GetCategories());
        }

        public ViewResult Category(string id)
        {
          TransactionManager tm = new TransactionManager();
          CategoryManager mm = new CategoryManager();
          Collection<ITransaction> trans = tm.GetAll().Where(t => t.Category.Name == id).ToCollection();

          TransactionViewData transactionViewData = new TransactionViewData(
            "Categories", null, trans);
          return View("TransactionList", transactionViewData);
      
        }
        public ViewResult NoCategories()
        {
          TransactionManager tm = new TransactionManager();
          TransactionViewData transactionViewData = new TransactionViewData(
            "NoCategories", null, tm.GetNoCategories());
          return View("TransactionList", transactionViewData);
        }
        public ViewResult ByWeek()
        {
             MoneyManager mm = new MoneyManager();
            Collection<Frogism.Core.Balance> list = mm.GetProgressByWeek();
            return View("MonthProgress", list);
        }

       public ViewResult Month()
        {
          MoneyManager mm = new MoneyManager();
          Collection<Frogism.Core.Balance> list = mm.GetProgressByMonth();
          return View("MonthProgress", list);
        }
       public ViewResult NewAccount()
       {
           Account a = new Account();

           return View("EditAccount", a);
       }
       public ViewResult EditAccount(int id)
       {
           var mm = new MoneyManager();
           var a = mm.Get(id);
           ViewData.Model = a;
           return View();
       }
        public ViewResult Year()
        {
          MoneyManager mm = new MoneyManager();
          Collection<Frogism.Core.Balance> list = mm.GetProgressByYear();
          return View("YearProgress", list);
        }
        public ViewResult LastWeek()
        {
          TransactionManager tm = new TransactionManager();
          TransactionViewData transactionViewData = new TransactionViewData("Last Week", null, tm.GetWeek(-1));
          return View("TransactionList", transactionViewData);
        }
        public ViewResult Week()
        {
          TransactionManager tm = new TransactionManager();
          TransactionViewData transactionViewData = new TransactionViewData("Week", null, tm.GetWeek());
          MoneyManager am = new MoneyManager();
          var builder = new Domain.YearBugetBuilder(DateTime.Now);
          var data = builder.GetYearSoFar( am.GetAll());
          ViewData["BudgetByWeek"] = data;
          return View("TransactionList", transactionViewData);
        }
        public ViewResult Recent()
        {
          TransactionManager tm = new TransactionManager();
          TransactionViewData transactionViewData = new TransactionViewData("Recent",null,tm.GetRecent());
          return View("TransactionList", transactionViewData);
        }
        public ViewResult New(string fromPage, int? fromId)
        {
          ITransaction t = new Transaction();
          t.Id = 0;
          t.IsConfirmed = false;
          t.TransactionDate = DateTime.Now.CleanDate();
          t.TransactionType = TransactionType.Create(DBConst.TransactionTypeExpense);
          t.AccountId = 1;
          TransactionEditViewData viewData =   CreateTransactionEditViewData(fromPage, fromId, t);
          return View("TransactionEdit", viewData);
        }
        public TransactionEditViewData CreateTransactionEditViewData(string fromPage, int? fromId, ITransaction t)
        {
            TransactionEditViewData viewData = new TransactionEditViewData(fromPage, fromId, t);
            ViewData["CategoryId"] = new SelectList(viewData.Categories, "Id", "Name", t.Category.Id);
            ViewData["TransactionTypeId"] = new SelectList(viewData.TransactionTypes, "Id", "Name", t.TransactionType.Value);
            ViewData["AccountId"] = new SelectList(viewData.Accounts, "Id", "Name",t.AccountId );
            return viewData;
        }
        public ActionResult Delete(int id)
        {
          TransactionManager tm = new TransactionManager();
          tm.Delete(id);
          return RedirectToAction("Index");
        }
        public ViewResult Edit(int id, string fromPage, int? fromId)
        {
          TransactionManager tm = new TransactionManager();
          ITransaction transaction = tm.Get(id);
          TransactionEditViewData transactionEditViewData = CreateTransactionEditViewData(fromPage, fromId, transaction);
       
          return View("TransactionEdit", transactionEditViewData);
        }
      
        public ActionResult Create(string Note, DateTime Date, int AccountId, int TransactionTypeId, decimal Amount, bool? IsConfirmed, int CategoryId)
        {
          //IsTopher();
          TransactionManager tm = new TransactionManager();
          Transaction t = new Transaction();
          t.AccountId = AccountId;
          t.TransactionType = TransactionType.Create(TransactionTypeId);
          t.Amount = Amount;
          t.TransactionDate = Date;
          t.IsConfirmed = IsConfirmed ?? false;
          t.Note = Note;
          t.Category = new ObjectNameBase() { Id = CategoryId, Name = "" };
          tm.Create(t);


          return RedirectToAction("Index");
        }
       
        public ActionResult Update(int? id, string Note, DateTime? TransactionDate, int AccountId, int TransactionTypeId, decimal Amount, bool? IsConfirmed, int CategoryId, string fromPage, int? fromId)
        {
          //IsTopher();
          TransactionManager tm = new TransactionManager();
          ITransaction t;
          if(id <= 0) {
            t = new Transaction();
          } else {
            t = tm.Get(id??-1);
          }
          t.AccountId = AccountId;
          t.TransactionType = TransactionType.Create(TransactionTypeId);
          t.Amount = Amount;
          t.TransactionDate = (DateTime)TransactionDate;
          t.IsConfirmed = IsConfirmed ?? false;
          t.Note = Note;
          t.Category = new ObjectNameBase() { Id = CategoryId, Name = "" };
          if(id <= 0) {
            tm.Create(t);
          } else {
            tm.Save(t);
          }

          if(fromPage != null && fromPage.Length > 0) {
            if(fromId == null || fromId < 0) {
                return RedirectToAction(fromPage);
            } else {
              System.Web.Routing.RouteValueDictionary rvd = new System.Web.Routing.RouteValueDictionary(new { action = fromPage, id = fromId });
              
              //RedirectToAction(rvd);
              return RedirectToAction(fromPage, rvd);
            }
          } else {
              return RedirectToAction("Index");
              //Response.Status = "303 See Other";
              //Response.AddHeader("Location", "Index");
              //Response.End();

             // Response.Redirect(Url.Action("Index"));
              //return Redirect("Index");
            // return Content("<script language='javascript' type='text/javascript'>self.location = '" + Url.Action("Index") + "';</script>");
          }
        }
    }
    public interface INetWorthViewData {
        IEnumerable<INetWorth> NetWorthItems { get; }
    }
    public interface ITransactionViewData {
      String ActionName { get; set; }
      int? Id { get; set; }
      IEnumerable<ITransaction> TransactionItems { get; }
      IEnumerable<IObjectNameBase> AccountItems { get; }
    }

    public class TransactionNewViewData {
      public TransactionNewViewData() {
        MoneyManager mm = new MoneyManager();
        CategoryManager cm = new CategoryManager();
        _Accounts = mm.GetAccountBasic();
        _TransactionTypes = mm.GetTransactionTypeBasic();
        _Categories = cm.GetCategoriesBasic().OrderBy(c=>c.Id).ToCollection<IObjectNameBase>();

      }
      public IEnumerable<IObjectNameBase> Categories { get { return _Categories; } }
      public IEnumerable<IObjectNameBase> Accounts { get { return _Accounts; } }
      public IEnumerable<IObjectNameBase> TransactionTypes { get { return _TransactionTypes; } }
      private IEnumerable<IObjectNameBase> _Accounts;
      private IEnumerable<IObjectNameBase> _Categories;
      private IEnumerable<IObjectNameBase> _TransactionTypes;
    }
    public class TransactionEditViewData : TransactionNewViewData {
      public TransactionEditViewData(string actionName, int? id, ITransaction transaction) {
        Transaction = transaction;
        ActionName = actionName;
        Id = id;
      }
      public String ActionName { get; set; }
      public int? Id { get; set; }
      public ITransaction Transaction;
    }

    public class TransactionViewData : ITransactionViewData {
        public TransactionViewData(string actionName, int? id, IEnumerable<ITransaction> transactions)
        {
        ActionName = actionName;
        Id = id;
        _TransactionItems = transactions;
        MoneyManager mm = new MoneyManager();
        _AccountItems = mm.GetAccountBasic();
      }
      public String ActionName { get; set; }
      public int? Id { get; set; }
      private IEnumerable<IObjectNameBase> _AccountItems;
      public IEnumerable<IObjectNameBase> AccountItems
      {
        get { return _AccountItems; }
      }
      private IEnumerable<ITransaction> _TransactionItems;
      public IEnumerable<ITransaction> TransactionItems
      {
        get { return _TransactionItems; }
      }
    }
    public class DashboardViewData : INetWorthViewData {
        public DashboardViewData(IEnumerable<IAccount> accounts, IEnumerable<IBudgetItem> budgetItems,
        IEnumerable<INetWorth> netWorthItems)
        {
        this._Accounts = accounts;
        this._BudgetItems = budgetItems;
        this._NetWorthItems = netWorthItems;
      }
        private IEnumerable<IAccount> _Accounts;
        public IEnumerable<IAccount> Accounts { get { return _Accounts; } }
        private IEnumerable<IBudgetItem> _BudgetItems;
        public IEnumerable<IBudgetItem> BudgetItems { get { return _BudgetItems; } }



        private IEnumerable<INetWorth> _NetWorthItems;
        public IEnumerable<INetWorth> NetWorthItems
        {
        get { return _NetWorthItems; }
      }
    }
}
